from selenium.common.exceptions import NoSuchElementException

from common.functions import get_xpath
from common.decorators import log4gs


@log4gs
class  FloatWindow(object):
    """浮窗（一般通过按钮触发的）描述符"""
    windowClassName = 'ivu-modal-content'
    headerClassName = 'ivu-modal-header-inner'
    closeClassName = 'ivu-modal-close'
    btnClassName = 'ivu-btn'

    def __init__(self, title=None, index=None, describe=None):
        """
        :param title: 浮窗的标题
        :param index: 浮窗序号
        :param describe: 浮窗描述

        使用方法：
            class Float(FloatWindow):
                def __init__(self, index=None):
                    super(Float, self).__init__(index=index)

            f1 = Float(index=1)   # 当前页面，类名是ivu-modal-content的第二个弹窗
        """
        if not title and not index and index != 0:
            try:
                raise ValueError("浮窗标题和浮窗序号至少提供一个")
            except ValueError:
                self.log.error("浮窗标题和浮窗序号至少提供一个", exc_info=True)

        self.title = title
        self.index = index
        self.describe = describe
        self.foot_right_btn_text = "确认,确定,完成"

    def __get__(self, instance, owner=None):
        self.driver = instance.driver
        find = False
        fws = self.driver.find_elements_by_class_name(self.windowClassName)
        if self.title:
            for fw in fws:
                header_text = fw.find_element_by_class_name(self.headerClassName).text.strip()
                if self.title == header_text:
                    self.fw = fw
                    find = True
                    break
            if not find:
                try:
                    raise Exception("没有找到title是‘{}’的弹窗".format(self.title))
                except Exception:
                    self.log.error("没有找到title是‘{}’的弹窗".format(self.title), exc_info=True)
        else:
            try:
                self.fw = fws[self.index]
            except Exception:
                self.log.error("通过序号‘{}’没有找到弹窗".format(self.index), exc_info=True)
        ### supply：提供一个统一的属性给其他地方用。比如通过弹窗（FloatWindow）可以获取其中的label，
        # 通过搜索区域（SearchTools）也要获取其中的label，此时ElementBaseLabel里面就可以统一用
        # instance.supply.find_elements_by_tag_name('label')来获取label元素了
        self.supply = self.fw
        self.foot_btns = self.fw.find_elements_by_class_name(self.btnClassName)
        if not self.foot_btns:
            try:
                raise NoSuchElementException("弹窗底部没有按钮")
            except NoSuchElementException:
                self.log.error("弹窗底部没有按钮", exc_info=True)

        return self

    @property
    def cancel(self):
        """获取弹窗的取消按钮，如果有的话"""
        find = False
        for btn in self.foot_btns:
            if '取消' in btn.text:
                find = True
                return btn
        if not find:
            try:
                raise NoSuchElementException("浮窗没有取消按钮")
            except NoSuchElementException:
                self.log.error("浮窗没有取消按钮", exc_info=True)

    @property
    def confirm(self):
        """获取弹窗的确认按钮，如果有的话"""
        find = False
        for btn in self.foot_btns:
            if btn.text.strip() in self.foot_right_btn_text.split(','):
                find = True
                return btn
        if not find:
            try:
                raise NoSuchElementException("浮窗没有{}按钮".format(self.foot_right_btn_text))
            except NoSuchElementException:
                self.log.error("浮窗没有{}按钮".format(self.foot_right_btn_text), exc_info=True)

    @property
    def upload(self):
        """导入"""
        self.foot_right_btn_text = "导入"
        return self.confirm

    @property
    def header_text(self):
        """获取表的标题名"""
        try:
            text = self.fw.find_element_by_class_name(self.headerClassName).text.strip()
            return text if text else ''
        except Exception:
            self.log.error("获取标题失败", exc_info=True)

    @property
    def xpath(self):
        """获取浮窗的xpath"""
        try:
            xpath = get_xpath(self.driver, self.fw)
            self.log.info("弹窗的xpath是：{}".format(xpath))
            return xpath
        except Exception:
            self.log.error("获取弹窗xpath失败", exc_info=True)

    def close(self):
        """右上角的关闭按钮"""
        try:
            self.fw.find_element_by_class_name(self.closeClassName).click()
        except Exception:
            self.log.error("获取弹窗右上角关闭按钮失败", exc_info=True)

    def get_btn(self, btn_name):
        """
        在ivu-modal-content中根据按钮名称获取按钮元素
        :param btn_name: 按钮名称
        :return: 按钮元素
        """
        btns = self.fw.find_elements_by_class_name(self.btnClassName)
        for btn in btns:
            if btn_name == btn.text.strip():
                return btn
        try:
            raise Exception("弹窗里面没有找到{}按钮".format(btn_name))
        except Exception:
            self.log.error("弹窗里面没有找到{}按钮".format(btn_name), exc_info=True)


class VisibleFloatWindow(FloatWindow):
    """当前可见的浮窗，适用于vue框架"""

    def __init__(self, driver):

        self.foot_right_btn_text = "确认,确定,完成"

        self.driver = driver
        fws = driver.find_elements_by_class_name(self.windowClassName)
        for fw in fws:
            if fw.is_displayed():
                self.fw = fw
                break
        self.foot_btns = self.fw.find_elements_by_class_name(self.btnClassName)
        if not self.foot_btns:
            try:
                raise NoSuchElementException("弹窗底部没有按钮")
            except NoSuchElementException:
                self.log.error("弹窗底部没有按钮", exc_info=True)


class WarningWindow(VisibleFloatWindow):
    """警告确认弹浮窗，适用于vue框架"""
    windowClassName = "ivu-modal-confirm"

    def __init__(self, driver):
        super(WarningWindow, self).__init__(driver)